using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Xml.Linq;
using System.IO;

namespace Entidades
{
    public class Usuario
    {
        private const string __ErrorAlta = "No se pudo dar el alta (Usuario), ";
        private const string __ErrorBaja = "No se pudo dar la baja (Usuario), ";
        private const string __ErrorModificacion = "No se pudo hacer la modificacion (Usuario), ";
        private const string __ErrorTraerUno = "No se pudo Traer Uno (Usuario), ";
        private const string __ErrorTraerTodos = "No se pudo Traer Todos (Usuario), ";
        private int _Id;
        private string _Password;
        private DateTime? _FechaAlta;
        private DateTime? _FechaBaja;

        private string _Email;

        private List<Contratacion> _ContratacionesRealizadas;



        #region "Propiedades"
        public int Id
        {
            get { return _Id; }
            set { _Id = value; }
        }
        public string Password
        {
            get { return _Password; }
            set { _Password = value; }
        }
        public DateTime? FechaAlta
        {
            get { return _FechaAlta; }
            set { _FechaAlta = value; }
        }
        public DateTime? FechaBaja
        {
            get { return _FechaBaja; }
            set { _FechaBaja = value; }
        }
        public string Email
        {
            get { return _Email; }
            set { _Email = value; }
        }

        public int cantidadContratacionesHechas { get; set; }
        public int cantidadContratacionesRecibidas { get; set; }
        public int cantidadCalificacionesPositivas { get; set; }
        public int cantidadCalificacionesNegativas { get; set; }
        public int cantidadRecomendacionesHechas { get; set; }
        public int cantidadRecomendacionesRecibidas { get; set; }
        public int cantidadPreguntasNoLeidas { get; set; }
        public int cantidadRespuestasNoLeidas { get; set; }


        public int CalificacionTotal
        {
            get { return cantidadCalificacionesPositivas - cantidadCalificacionesNegativas + cantidadRecomendacionesRecibidas; }
        }



        #endregion
        #region "Lazys"
        public List<Contratacion> ContratacionesRealizadas
        {
            get
            {
                if (_ContratacionesRealizadas == null)
                {
                    _ContratacionesRealizadas = Contratacion.getAllRealizadasByIdUsuario(_Id);
                }
                return _ContratacionesRealizadas;
            }
        }

        private List<Contratacion> _ContratacionesRecibidas;
        public List<Contratacion> ContratacionesRecibidas
        {
            get
            {
                if (_ContratacionesRecibidas == null)
                {
                    _ContratacionesRecibidas = Contratacion.getAllRecibidasByIdUsuario(_Id);
                }
                return _ContratacionesRecibidas;
            }
        }

        private List<Contratacion> _ContratacionesSinCalificar;
        public List<Contratacion> ContratacionesSinCalificar
        {
            get
            {
                if (_ContratacionesSinCalificar == null)
                {
                    _ContratacionesSinCalificar = Contratacion.getAllContratacionesSinCalificarByIdUsuario(_Id);
                }
                return _ContratacionesSinCalificar;
            }
        }


        private Perfil _Perfil;
        public Perfil Perfil
        {
            get
            {
                if (_Perfil == null)
                {
                    _Perfil = Entidades.Perfil.getOneByIdUsuario(_Id);
                }
                return _Perfil;
            }
        }
        private List<Postulacion> _Postulaciones;
        public List<Postulacion> Postulaciones
        {
            get
            {
                if (_Postulaciones == null)
                {
                    _Postulaciones = Postulacion.getAllByIdUsuario(_Id);
                }
                return _Postulaciones;
            }
        }
        private List<Pregunta> _Preguntas;
        public List<Pregunta> Preguntas
        {
            get
            {
                if (_Preguntas == null)
                {
                    _Preguntas = Pregunta.getAllByIdUsuario(_Id);
                }
                return _Preguntas;
            }
        }

        private List<Pregunta> _PreguntasRecibidas;

        public List<Pregunta> PreguntasRecibidas
        {
            get
            {
                if (_PreguntasRecibidas == null)
                {
                    _PreguntasRecibidas = Pregunta.TraerTodasParaElUsuario(_Id);
                }
                return _PreguntasRecibidas;
            }
        }



        private List<Recomendacion> _Recomendaciones;
        public List<Recomendacion> Recomendaciones
        {
            get
            {
                if (_Recomendaciones == null)
                {
                    _Recomendaciones = Recomendacion.getAllByIdUsuario(_Id);
                }
                return _Recomendaciones;
            }
        }
        #endregion
        public Usuario()
        {
        }
        public Usuario(int Id)
        {
            Usuario usuario = traerUno(Id);
            this._Id = usuario.Id;
            this._Password = usuario.Password;
            this._FechaAlta = usuario.FechaAlta;
            this._FechaBaja = usuario.FechaBaja;
            this._Email = usuario.Email;
            this.cantidadContratacionesHechas = usuario.cantidadContratacionesHechas;
            this.cantidadContratacionesRecibidas = usuario.cantidadContratacionesRecibidas;
            this.cantidadCalificacionesPositivas = usuario.cantidadCalificacionesPositivas;
            this.cantidadCalificacionesNegativas = usuario.cantidadCalificacionesNegativas;
            this.cantidadRecomendacionesHechas = usuario.cantidadRecomendacionesHechas;
            this.cantidadRecomendacionesRecibidas = usuario.cantidadRecomendacionesRecibidas;
            this.cantidadPreguntasNoLeidas = usuario.cantidadPreguntasNoLeidas;
            this.cantidadRespuestasNoLeidas = usuario.cantidadRespuestasNoLeidas;
            
        }
        #region "Metodos Publicos"
        public void Alta()
        {
            try
            {
                validaAlta();
                DALUsuario.Alta(this);
            }
            catch (Exception ex)
            {
                throw new Exception(__ErrorAlta + ex.Message);
            }
        }
        public void Baja()
        {
            try
            {
                validaBaja();
                DALUsuario.Baja(_Id);
            }
            catch (Exception ex)
            {
                throw new Exception(__ErrorBaja + ex.Message);
            }
        }
        public void Modificar()
        {
            try
            {
                validaModificacion();
                DALUsuario.Modificar(this);
            }
            catch (Exception ex)
            {
                throw new Exception(__ErrorModificacion + ex.Message);
            }
        }
        public void AltaDefinitiva()
        {
            try
            {
                DALUsuario.AltaDefinitiva(this.Id);
            }
            catch (Exception ex)
            {
                throw new Exception(__ErrorModificacion + ex.Message);
            }
        }
         public static List<Usuario> traerUltimosRegistrados()
        {
            return DALUsuario.traerUltimosRegistrados();
        }


        #region "Metodos Estaticos"
        private Usuario traerUno(int Id)
        {
            try
            {
                return DALUsuario.traerUno(Id);
            }
            catch (Exception ex)
            {
                throw new Exception(__ErrorTraerUno + ex.Message);
            }
        }

        public static Usuario login(string email, string password)
        {
            Usuario us = null;
            try
            {
                us = DALUsuario.traerUno(email, password);
                if ((us != null))
                {
                    return us;
                }
            }
            catch (Exception)
            {
                throw new Exception("Ha ocurrido un error en el logueo, por favor intentelo mas tarde");
            }
            throw new Exception("Usuario o clave Incorrectos");
        }


        public static Usuario traerUnoXEmail(string email)
        {
            try
            {
                return DALUsuario.TraerUnoXEmail(email);
            }
            catch (Exception ex)
            {
                throw new Exception(__ErrorTraerUno + ex.Message);
            }
        }

        #endregion
        #endregion
        #region "Metodos Privados"
        private void validaAlta()
        {
            ////lanza excepcion si no valida
            //if (_Email.Trim() == "")
            //    throw new Exception("Ingrese el email");
            //if (_Password.Trim() == "")
            //    throw new Exception("Ingrese el password");

            string strError = "";

            if (_Email.Trim() == "")
                strError += "* Ingrese el email ";
            if (_Password.Trim() == "")
                strError += "* Ingrese el password";

            if (strError != "")
                throw new Exception(strError);


        }
        private void validaBaja()
        {
            //lanza excepcion si no valida
            throw new NotImplementedException();
        }
        private void validaModificacion()
        {
            validaAlta();
        }
        #endregion

        public static Usuario registrar(string Apellido, string Nombre, string Email, string Password, System.DateTime? fechaNacimiento, string Sexo)
        {
            Usuario us = traerUnoXEmail(Email);
            if ((us != null))
            {
                throw new Exception("ERROR!!! El mail ya está registrado");
            }
            else
            {
                try
                {
                    us = new Usuario();
                    us._Email = Email;
                    us.Password = Password;
                    us.Alta();
                    Perfil per = new Perfil();
                    per.IdUsuario = us.Id;
                    per.Nombre = Nombre;
                    per.Apellido = Apellido;
                    per.FechaNacimiento = fechaNacimiento;
                    per.Sexo = Sexo;
                    per.Alta();


                    string mail = traerMail();
                    mail = mail.Replace("xxx", Criptografia.Criptografia.Encripta(us.Id.ToString()));
                    mail = mail.Replace("yyy", Criptografia.Criptografia.Encripta(us.Email));
                    //Estos de aca son cualquier cosa///
                    int num1 = numeroAzar(20000, 100000);
                    int num2 = numeroAzar(30000, 100000);
                    mail = mail.Replace("zzz", Criptografia.Criptografia.Encripta(num1.ToString()));
                    mail = mail.Replace("bbb", Criptografia.Criptografia.Encripta(num2.ToString()));
                    envioMails.Envio.mandarMail(us.Email, "Bienvenido a Recomendados.com", mail);
                }
                catch (Exception ex)
                {
                    throw new Exception("Se ha producido un error al registrar el usuario." + ex);
                }

            }
            return us;
        }

        private static string traerMail()
        {
            StringWriter sw = new StringWriter();
            sw.WriteLine("Le damos la bienvenida a \"Recomendados.com\"");
            sw.WriteLine("Para continuar con el registro haga click en el siguiente elnace");
            sw.WriteLine("<a href=\"http://localhost:1664/SitioRecomendados/Cuenta/Activacion.aspx?Ia=zzz&Iu=xxx&Um=yyy&ul=bbb\">http://localhost:1664/SitioRecomendados/Cuenta/Activacion.aspx?Ia=zzz&Iu=xxx&Um=yyy&ul=bbb</a>");
            sw.WriteLine("");
            sw.WriteLine("");
            sw.WriteLine("");
            sw.WriteLine("Muchas Gracias!!!");
            return sw.ToString();
        }

        private static int numeroAzar(int minimo, int maximo)
        {
            Random rndNum = new Random(int.Parse(Guid.NewGuid().ToString().Substring(0, 8), System.Globalization.NumberStyles.HexNumber));

            int rnd = rndNum.Next(minimo, maximo);

            return rnd;
        }

        private List<Recomendacion> _RecomendacionesRecibidas;
        public List<Recomendacion> RecomendacionesRecibidas
        {
            get
            {
                if (_RecomendacionesRecibidas == null)
                {
                    _RecomendacionesRecibidas = Recomendacion.getAllRecibidasByIdUsuario(_Id);
                }
                return _RecomendacionesRecibidas;
            }
        }



       
    }
}
